// 定义一个常量defaultConfig，它是一个对象，包含了一些默认的请求配置选项
const defaultConfig = {
  // 设置请求的基本URL，它的值是从import.meta.env对象中获取的VITE_BASE_URL属性，这个属性是在.env文件中定义的环境变量
  baseURL: import.meta.env.VITE_BASE_URL,
  // 设置请求的超时时间，它的值是从import.meta.env对象中获取的VITE_REQUEST_TIME_OUT属性，这个属性也是在.env文件中定义的环境变量
  timeout: import.meta.env.VITE_REQUEST_TIME_OUT,
  // 设置响应的数据类型，这里是json格式
  dataType: "json",
  transformRequest:[
      (data) =>{
          data = JSON.stringify(data);
          return data;
      }
  ],
  validateStatus(){
      return true;
  },
  transformResponse:[
      (data) =>{
          if(typeof data  === "string" && data.startsWith("{")){
              data = JSON.parse(data);
          }
          console.log(data)
          return data;
      },
  ],
  // 设置请求头对象，用于设置一些额外的信息，如内容类型、请求来源等
  header: {
    // Accept: "application/json, text/plain, */*",
    "Content-Type": "application/json",
    // "X-Requested-With": "XMLHttpRequest",
  }
};

/**
 * 获取一个合并了默认配置和自定义配置的配置对象
 * @param config
 */
const getConfig = (config?: any): any => {
  if (!config) return defaultConfig;
  return Object.assign({}, defaultConfig, config);
};

class httpRequest {
  constructor() {
    this.httpInterceptorsRequest();
    this.httpInterceptorsResponse();
  }

  private static async request(config: any): Promise<any> {
    // 使用uni.request方法发送网络请求，并返回一个Promise对象
    return await  uni.request(config);
  }

  private httpInterceptorsRequest(): void {
    // 在每次发送请求之前，对请求的配置对象进行修改或添加一些逻辑
    httpRequest.request = (config: any) => {
      // 获取token值，token是一种用于身份验证的令牌
      const token = uni.getStorageSync("token");
      // 如果token存在，并且config对象有header属性
      if (token && config.header) {
        // 则在header对象中设置一个名为token的字段，值为token
        // 这样可以在发送请求时，将token作为请求头的一部分，用于验证用户身份
        config.header.token = token;
      }
      // 返回修改后的config对象，继续发送请求
      return config;
    };
  }

  private httpInterceptorsResponse(): void {
    // 在每次接收响应之后，对响应的数据进行处理或添加一些逻辑
    httpRequest.request = async (config: any) => {
      try {
        // 发送请求，并等待响应结果
        const response = await uni.request(config);
        // 获取响应数据
        const res = response.data;
        // 如果响应状态码不等于200
        if (response.Code != 200) {
          // 弹出错误提示信息
          uni.showToast({
            title: "请求错误",
            icon: "error",
            duration: 5 * 500,
          });
          // 返回响应数据
          return res;
        }
        // 如果响应数据中的code等于200
        if (res.code === 200) {
          // 返回响应数据
          return res;
        }
        // 如果响应数据中的code不等于200
        if (res.code != 200) {
          // 弹出错误提示信息
          uni.showToast({
            title: res.msg,
            icon: "error",
            duration: 5 * 500,
          });
          // 返回响应数据
          return res;
        }
      } catch (error) {
        // 处理错误信息
        console.error(error);
        // 弹出错误提示信息
        uni.showToast({
          title: error.message,
          icon: "error",
          duration: 5 * 500,
        });
        // 返回一个被拒绝的Promise对象，中断请求流程
        return Promise.reject(error);
      }
    };
  }

  public reqGet(url: string, params?: unknown, config?: any): Promise<any> {
    // 调用request方法，并传入一个配置对象，包含url、method、data等参数
    return httpRequest.request(
      getConfig({
        url: url,
        method: "GET",
        data: params,
        ...config,
      })
    );
  }

  public reqPost(url: string, params?: unknown, config?: any): Promise<any> {
    // 调用request方法，并传入一个配置对象，包含url、method、data等参数
    return httpRequest.request(
      getConfig({
        url: url,
        method: "POST",
        data: params,
        ...config,
      })
    );
  }

  public get(url: string, params?: unknown, config?: any): Promise<any> {
    // 直接使用uni.request方法，并传入一个配置对象，包含url、method、data等参数
    return uni.request(
      getConfig({
        url: url,
        method: "GET",
        data: params,
        ...config,
      })
    );
  }

  public post(url: string, params?: unknown, config?: any): Promise<any> {
    // 直接使用uni.request方法，并传入一个配置对象，包含url、method、data等参数
    return uni.request(
      getConfig({
        url: url,
        method: "POST",
        data: params,
        ...config,
      })
    );
  }
}

export default httpRequest;
